package com.example.securityconfig.filter;


import com.example.securityconfig.entity.LoginUser;
import com.example.securityconfig.entity.enums.RedisKeyEnum;
import com.example.securityconfig.util.JwtTokenUtil;
import com.example.securityconfig.util.RedisUtil;
import com.google.gson.Gson;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Objects;

@Component
@Log4j2
public class JwtSecurityFilter extends OncePerRequestFilter {

    @Autowired
    private RedisUtil redisService;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException {

        //获取请求的接口
        String path = request.getRequestURI();
        log.info("当前请求接口：" + path);
        //获取请求头
        String token = request.getHeader(RedisKeyEnum.REDIS_KEY_HEADER_INFO.getKey());

        //从缓存中获取jwt
        Object sessionJwt =redisService.get(RedisKeyEnum.REDIS_KEY_USER_INFO.getKey() + token);
        if(sessionJwt==null){
            filterChain.doFilter(request, response);
            return;
        }
        String jwt = String.valueOf(sessionJwt);

        String usernameFromToken = jwtTokenUtil.getUsernameFromToken(jwt);
//        //反序列化转为UserDto对象
        LoginUser loginUser = new Gson().fromJson(usernameFromToken, LoginUser.class);
        // 校验用户信息
        if (Objects.isNull(loginUser)) {
            throw new RuntimeException("用户未登录");
        }
        // 存入 SecurityContextHolder   参数一：用户信息   参数二：  参数三：权限认证
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =
                                    new UsernamePasswordAuthenticationToken(loginUser.getUsers(), null, loginUser.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
//        // 放行
        filterChain.doFilter(request, response);
    }
}